package org.esgl3d.rendering;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;

import android.R.integer;



public abstract class VertexContainer {
	
	public enum PrimitiveType {
		Triangle,
		TriangleStrip,
		Line,
		Quad,
		Point
	}
		
	/**
	 * Type of Buffer
	 * @author michael
	 */
	public enum BufferStructure {
		Stacked,
		Interleaved,
	}
	
	protected final FloatBuffer buffer;
	protected final int numberOfVertices;
	protected final VertexFormat format;
	protected final BufferStructure structure;
	
	VertexContainer(int setNumberOfVertices, VertexFormat ftype) {
		buffer = ByteBuffer.allocateDirect(setNumberOfVertices * (ftype.totalFloats*4))
		.order(ByteOrder.nativeOrder())
		.asFloatBuffer();
		numberOfVertices = setNumberOfVertices;
		format = ftype;
		structure = BufferStructure.Interleaved;
	}

	public abstract void draw(PrimitiveType type, int startingVertice, int numberOfVertices);
	
	/**
	 * Synchronizes the buffer with the one in video memory.
	 */
	public abstract void synchronize();
	
	private void putValues(int index, int type, float... data) {
		if (format.components[type]== 0)
			return;
		
		if (structure == BufferStructure.Stacked) 
			buffer.position(format.offsets[type] * numberOfVertices + format.components[type] * index);
		else
			buffer.position(format.totalFloats * index + format.offsets[type]);
		
		buffer.put(data[0]);
		buffer.put(data[1]);
		if (format.components[type]==3)
			buffer.put(data[2]);
		if (format.components[type]==4)
			buffer.put(data[3]);
	}
		
	/**
	 * Sets positional data at the specified index
	 * @param index
	 * @param data
	 */
	public void setPosition(int index, float... data) {
		putValues(index, VertexFormat.POSITION, data);
	}
	
	/**
	 * Sets texture u/v coordinates at the specified index
	 * @param index
	 * @param data
	 */
	public void setTexture(int index, float... data) {
		putValues(index, VertexFormat.TEXTURE, data);
	}
	
	/**
	 * Sets color information at the specified index
	 * @param index
	 * @param data
	 */
	public void setColor(int index, float... data) {
		putValues(index, VertexFormat.COLOR, data);
	}
	
	/**
	 * Returns a new legacy wrapper.
	 * @return a new wrapper object which wraps this container
	 */
	public LegacyGLWrapper getLegacyGLInterface() {
		return new LegacyGLWrapper(buffer,format, this);
	}

	/**
	 * @return number of vertices in this container
	 */
	public int getNumberOfVertices() {
		return numberOfVertices;
	}

	/**
	 * releases the buffer
	 */
	public void release() {
		// TODO Auto-generated method stub
		
	}

}
